package com.guoxin.part4.chapter17;

/**
 * ReadWriteLock implement
 *
 * @author guoxin
 * @date 2019/8/30
 */
class ReadWriteLockImpl implements ReadWriteLock {
    /**
     * 定义对象锁
     */
    private final Object MUTEX = new Object();

    /**
     * 当前有多少个线程正在写入
     */
    private int writingWriters = 0;

    /**
     * 当前有多少个线程正在等待写入
     */
    private int waitingWriters = 0;

    /**
     * 当前有多少个线程正在read
     */
    private int readingReaders = 0;

    /**
     * read和write的偏好设置
     */
    private boolean preferWriter;

    ReadWriteLockImpl() {
        this(true);
    }

    ReadWriteLockImpl(boolean preferWriter) {
        this.preferWriter = preferWriter;
    }

    /**
     * 创建read lock
     *
     * @return ReadLock
     */
    @Override
    public Lock readLock() {
        return new ReadLock(this);
    }

    /**
     * 创建 write lock
     *
     * @return WriteLock
     */
    @Override
    public Lock writeLock() {
        return new WriteLock(this);
    }

    /**
     * 使写线程的数量增加
     */
    void incrementWritingWriters() {
        this.writingWriters++;
    }

    /**
     * 使等待写入的线程数量增加
     */
    void incrementWaitingWriters() {
        this.waitingWriters++;
    }

    /**
     * 使读线程的数量增加
     */
    void incrementReadingReaders() {
        this.readingReaders++;
    }

    /**
     * 使写线程的数量减少
     */
    void decrementWritingWriters() {
        this.writingWriters--;
    }

    /**
     * 使等待获取写入锁的数量减一
     */
    void decrementWaitingWriters() {
        this.waitingWriters--;
    }

    /**
     * 使读取线程的数量减少
     */
    void decrementReadingReaders() {
        this.readingReaders--;
    }

    /**
     * 获取当前有多少个线程在进行写操作
     *
     * @return 写操作线程数
     */
    @Override
    public int getWritingWriters() {
        return this.writingWriters;
    }

    /**
     * 获取当前有多少个线程正在等待获取写入锁
     *
     * @return 等待获取写入锁的线程数
     */
    @Override
    public int getWaitingWriters() {
        return this.waitingWriters;
    }

    /**
     * 获取当前多少个线程正在进行读操作
     *
     * @return 当前读操作的线程数
     */
    @Override
    public int getReadingReaders() {
        return this.readingReaders;
    }

    /**
     * 获取对象锁
     *
     * @return 对象锁
     */
    Object getMutex() {
        return MUTEX;
    }

    /**
     * 获取当前是否偏向锁
     *
     * @return boolean
     */
    boolean getPreferWriter() {
        return preferWriter;
    }

    /**
     * 设置写锁偏好
     *
     * @param preferWriter boolean
     */
    void changePrefer(boolean preferWriter) {
        this.preferWriter = preferWriter;
    }

}
